<?php
/**
 * Mailer.php
 *
 * @author Hua Yang <htmlcook@gmail.com>
 * @since 2.0
 */

Yii::import('common.components.mail.YBaseMailer');

/**
 * Class Mailer
 */
class Mailer extends YBaseMailer
{
	public $messageClass = 'common.components.mail.swiftmailer.Message';

	/**
	 * @var Swift_MailTransport
	 */
	private $_transport;

	/**
	 * @var Swift_Mailer
	 */
	private $_swiftMailer;

	public function init()
	{
		parent::init();
		require dirname(__FILE__) . '/lib/swift_required.php';
		Yii::registerAutoloader(array('Swift', 'autoload'), true);
	}

	/**
	 * @param YBaseMessage $message
	 * @return bool
	 */
	public function sendMessage($message)
	{
		$address = $message->getTo();
		if (is_array($address)) {
			$address = implode(', ', array_keys($address));
		}
		Yii::log('Sending email "' . $message->getSubject() . '" to "' . $address . '"');
		return $this->getSwiftMailer()->send($message->getSwiftMessage()) > 0;
	}

	/**
	 * @return Swift_Mailer
	 */
	public function getSwiftMailer()
	{
		if (!isset($this->_swiftMailer)) {
			$this->_swiftMailer = $this->createSwiftMailer();
		}
		return $this->_swiftMailer;
	}

	/**
	 * @return Swift_Mailer
	 */
	public function createSwiftMailer()
	{
		return Swift_Mailer::newInstance($this->getTransport());
	}

	/**
	 * @return Swift_MailTransport
	 */
	public function getTransport()
	{
		if (!is_object($this->_transport)) {
			$this->_transport = $this->createTransport($this->_transport);
		}
		return $this->_transport;
	}

	/**
	 * @param $transport
	 * @throws CException
	 */
	public function setTransport($transport)
	{

		if (!is_array($transport) && !is_object($transport)) {
			throw new CException('transport 必须是数组或一个对象');
		}
		$this->_transport = $transport;
	}

	/**
	 * @param array $config
	 * @return Swift_MailTransport
	 */
	public function createTransport(array $config)
	{
		if (!isset($config['class'])) {
			$config['class'] = 'Swift_MailTransport';
		}
		if (isset($config['plugins'])) {
			$plugins = $config['plugins'];
			unset($config['plugins']);
		}
		/** @var Swift_MailTransport $transport */
		$transport = $this->createSwiftObject($config);
		if (isset($plugins)) {
			foreach ($plugins as $plugin) {
				if (is_array($plugin) && isset($plugin['class'])) {
					$plugin = $this->createSwiftObject($plugin);
				}
				$transport->registerPlugin($plugin);
			}
		}

		return $transport;
	}

	/**
	 * @param $config
	 * @return object
	 * @throws CException
	 */
	public function createSwiftObject($config)
	{
		if (isset($config['class'])) {
			$className = $config['class'];
			unset($config['class']);
		} else {
			throw new CException('配置对象必须包含一个"class"元素');
		}
		if (!class_exists($className, false)) {
			$className = Yii::import($className, true);
		}
		$reflection = new ReflectionClass($className);
		if (isset($config['constructArgs']) && is_array($config['constructArgs'])) {
			$args = array();
			foreach ($config['constructArgs'] as $arg) {
				if (is_array($arg) && isset($arg['class'])) {
					$args[] = $this->createSwiftObject($arg);
				} else {
					$args[] = $arg;
				}
			}
			unset($config['constructArgs']);
			$object = $reflection->newInstanceArgs($args);
		} else {
			$object = new $className;
		}
		if (!empty($config)) {
			foreach ($config as $name => $value) {
				if (property_exists($object, $name)) {
					$object->$name = $value;
				} else {
					$setter = 'set' . $name;
					if (method_exists($object, $setter) || method_exists($object, '__call')) {
						$object->$setter($value);
					} else {
						throw new CException('未知的属性: ' . $className . '::' . $name);
					}
				}
			}
		}
		return $object;
	}
}
